////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 CORE Solutions Limited
// All rights reserved.
// PROPRIETARY AND CONFIDENTIAL INFORMATION.
// Use is subject to license terms.
//
// FUNCTION ID      :   
// AUTHOR           :    
// DATE CREATE      :   
// DESCRIPTION      :   
//                  :   
//                  :   
//                  :   
//
// MODIFICATION HISTORY:
// DATE         AUTHOR          VERSION NO.         COMMENT
// -----------  --------------  ------------------  -------------------
// 2006/05/09   Ric Yik         1.0                 BugZilla #5635
// 2006/05/17   Ric Yik         1.0                 BugZilla #5796
// 2006/06/23   Ric Yik         1.0                 BugZilla #5535
//
////////////////////////////////////////////////////////////////////////////////

package com.erp.framework.controller.action;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.erp.app.admin.companySetup.criteria.CompanyImageSrchCriteria;
import com.erp.app.admin.companySetup.vo.CompanyImageVo;
import com.erp.framework.SimpleConstants;
import com.erp.framework.controller.form.SimpleBaseForm;
import com.erp.framework.exceptions.FindRecordException;
import com.erp.framework.model.delegate.SimpleSearchMaintStyleDelegate;
import com.erp.framework.util.logger.Logger;

public abstract class SimpleBaseAction extends Action implements Serializable, SimpleConstants {

    public static final String SESSION_REQUEST_HANDLED = "SESSION_REQUEST_HANDLED";

    // To be compatible with Struts 1.0
    public final ActionForward perform(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) throws ServletException {

        beforeExecuteAction(mapping, formIn, request, response);
        ActionForward forward = execute(mapping, formIn, request, response);
        afterExecuteAction(mapping, formIn, request, response);
        return forward;
    }

    protected void cleanupAction(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) {

    }

    protected void beforeExecuteAction(ActionMapping mapping, ActionForm formIn, HttpServletRequest request, HttpServletResponse response) {

    }

    protected void afterExecuteAction(ActionMapping mapping, ActionForm formIn, HttpServletRequest request, HttpServletResponse response) {

    }

    // NOT intended to be overridden by subclasses
    public final ActionForward execute(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) throws ServletException {

        ActionForward actionForward = null;
        try {
            this.beforeTry(mapping, formIn, request, response);
            // creates a new session
            HttpSession session = request.getSession(false);
            SimpleBaseForm form = (SimpleBaseForm) formIn;
            request.setAttribute(SimpleConstants.REQUEST_FROMBEAN_NAME, form);
            actionForward = new ActionForward(mapping.getInput());

            initLoad();

            if (session != null) {
                // reset handled
                resetHandled(request);
                actionForward = coreExecute(mapping, formIn, request, response);

                if (actionForward != null) {
                    Logger.debug(this, "execute(), after coreExecute, actionForward=[" + actionForward.getPath() + "]");
                }
                if (!isHandled(request)) {
                    // initAction(mapping, formIn, request, response);
                    actionForward = otherExecute(mapping, formIn, request, response);

                    if (actionForward != null) {
                        Logger.debug(this, "execute(), after otherExecute, actionForward=[" + actionForward.getPath() + "]");
                    }

                    if (!isHandled(request)) {
                        actionForward = new ActionForward(mapping.getInput());
                    }
                    cleanupAction(mapping, formIn, request, response);
                }

                resetHandled(request);
            } else {
                actionForward = mapping.findForward("login");
            }

            if (actionForward != null) {
                if (getNeedSetGotoURL()) {
                    form.setGotoURL(actionForward.getPath());
                    actionForward = new ActionForward(mapping.getInput());
                }
            }
        } catch (ServletException e) {
            Logger.logExceptions(this, e);
            throw e;
        } catch (Exception e) {
            Logger.logExceptions(this, e);
        } finally {
            this.onFinally(mapping, formIn, request, response);
            response.setHeader("Expires", "Tue, 28 Dec 1993 23:59:59 GMT");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-control", "no-cache");
        }
        return actionForward;
    }

    protected void beforeTry(ActionMapping mapping, ActionForm formIn, HttpServletRequest request, HttpServletResponse response) {
    }

    protected void onFinally(ActionMapping mapping, ActionForm formIn, HttpServletRequest request, HttpServletResponse response) {
    }


    protected void resetHandled(HttpServletRequest request) {

        getSession(request).setAttribute(SESSION_REQUEST_HANDLED, "");
    }

    protected void setHandled(HttpServletRequest request) {

        getSession(request).setAttribute(SESSION_REQUEST_HANDLED, "handled");
    }

    protected boolean isHandled(HttpServletRequest request) {

        return (!("".equals(getSession(request).getAttribute(SESSION_REQUEST_HANDLED))));
    }

    protected HttpSession getSession(HttpServletRequest request) {

        return request.getSession();
    }

    // To be overridden by UserAction ONLY
    protected ActionForward coreExecute(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) throws ServletException {

        return baseCoreExecute(mapping, formIn, request, response);
    }

    // NOT intended to be overridden by subclasses
    protected final ActionForward baseCoreExecute(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) throws ServletException {

        return null;
    }

    // To be overridden by subclasses other than UserAction
    protected ActionForward otherExecute(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) throws ServletException {

        return null;
    }

    protected boolean getNeedSetGotoURL() {

        return false;
    }

    private void initLoad() {
        ServletContext servletContext = servlet.getServletContext();
        Boolean isLoaded = (Boolean) servletContext.getAttribute(SERVLET_ATTRIB_KEY_INIT_LOADED);

        if (isLoaded != null && isLoaded.booleanValue())
            return;

        try {
            loadCompaniesImages(servletContext);
        } catch (Exception e) {
            Logger.logExceptions(this, e);
        }

        servletContext.setAttribute(SERVLET_ATTRIB_KEY_INIT_LOADED, Boolean.TRUE);
    }

    private void loadCompaniesImages(ServletContext servletContext) throws FindRecordException, RemoteException {
        SimpleSearchMaintStyleDelegate md = new SimpleSearchMaintStyleDelegate();

        ArrayList list = (ArrayList) md.findByCriteria(new CompanyImageVo(), new CompanyImageSrchCriteria());
        HashMap logoMap = new HashMap();
        HashMap bgMap = new HashMap();
        CompanyImageVo vo = null;
        for (Iterator it = list.iterator(); it.hasNext();) {
            vo = (CompanyImageVo) it.next();

            if (vo == null)
                continue;

            if (vo.getId().equals(IMAGE_TOP_BANNER_LOGO)) {
                logoMap.put(vo.getCompanyCode(), vo);
            } else if (vo.getId().equals(IMAGE_TOP_BANNER_BG)) {
                bgMap.put(vo.getCompanyCode(), vo);
            }
        }

        servletContext.setAttribute(SERVLET_ATTRIB_KEY_COMPANIES_LOGO, logoMap);
        servletContext.setAttribute(SERVLET_ATTRIB_KEY_COMPANIES_BG, bgMap);
    }
}